
///////////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2002, Perry L. Miller IV
//  All rights reserved.
//  BSD License: http://www.opensource.org/licenses/bsd-license.html
//
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
//
//  Curve of doubles.
//
///////////////////////////////////////////////////////////////////////////////

#include "Precompiled.h"
#include "CurveDouble.h"

#include "GN/Splines/Curve.h"
#include "GN/Algorithms/FindSpan.h"
#include "GN/Algorithms/BasisFunctions.h"
#include "GN/Algorithms/Parameterize.h"
#include "GN/Algorithms/KnotVector.h"
#include "GN/Evaluate/Point.h"
#include "GN/Interpolate/Global.h"

using namespace GN;
using namespace GN::Components;

USUL_IMPLEMENT_IUNKNOWN_MEMBERS ( CurveDouble , CurveDouble::BaseClass );


///////////////////////////////////////////////////////////////////////////////
//
//  Constructor.
//
///////////////////////////////////////////////////////////////////////////////

CurveDouble::CurveDouble() : BaseClass(),
  _curve()
{
}


///////////////////////////////////////////////////////////////////////////////
//
//  Destructor.
//
///////////////////////////////////////////////////////////////////////////////

CurveDouble::~CurveDouble()
{
}


///////////////////////////////////////////////////////////////////////////////
//
//  Query for the interface.
//
///////////////////////////////////////////////////////////////////////////////

Usul::Interfaces::IUnknown *CurveDouble::queryInterface ( unsigned long iid )
{
  switch ( iid )
  {
  case GN::Interfaces::ICurveDouble::IID:
    return static_cast<GN::Interfaces::ICurveDouble*>(this);
  case GN::Interfaces::IEvaluatePointDouble::IID:
    return static_cast<GN::Interfaces::IEvaluatePointDouble*>(this);
  case GN::Interfaces::IInterpolateGlobalDouble::IID:
    return static_cast<GN::Interfaces::IInterpolateGlobalDouble*>(this);
  case Usul::Interfaces::IUnknown::IID:
    return static_cast<Usul::Interfaces::IUnknown*>(static_cast<GN::Interfaces::ICurveDouble*>(this));
  default:
    return 0x0;
  }
}


///////////////////////////////////////////////////////////////////////////////
//
//  Get the number of dependent variables.
//
///////////////////////////////////////////////////////////////////////////////

CurveDouble::SizeType CurveDouble::numDepVars() const
{
  return _curve.numDepVars();
}


///////////////////////////////////////////////////////////////////////////////
//
//  Get the order of the curve (degree+1).
//
///////////////////////////////////////////////////////////////////////////////

CurveDouble::SizeType CurveDouble::order() const
{
  return _curve.order();
}


///////////////////////////////////////////////////////////////////////////////
//
//  Is it rational?
//
///////////////////////////////////////////////////////////////////////////////

bool CurveDouble::rational() const
{
  return _curve.rational();
}


///////////////////////////////////////////////////////////////////////////////
//
//  Evaluate the point at the given parameter.
//
///////////////////////////////////////////////////////////////////////////////

void CurveDouble::evaluatePoint ( const IndependentType &u, DependentVector &point, Unknown *caller ) const
{
  GN::Evaluate::point ( _curve, u, point );
}


///////////////////////////////////////////////////////////////////////////////
//
//  Interpolate the points. 
//  Dimension = points.size(). Independents = order.size().
//
///////////////////////////////////////////////////////////////////////////////

void CurveDouble::interpolateGlobal ( unsigned int order, const DependentMatrix &points, Unknown *caller )
{
  GN::Interpolate::global ( order, points, GN::Algorithms::Constants::CENTRIPETAL_FIT, _curve );
}
